package com.magicalcoder.pigeontest.spring.adminuser.impl;

import com.magicalcoder.pigeontest.model.AdminUser;
import com.magicalcoder.pigeontest.service.AdminUserTxService;
import com.magicalcoder.pigeontest.spring.mapper.AdminUserMapper;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.Date;

/**
 * Created by hedongyu on 2017/7/31.
 */
@Service("adminUserTxService")
public class AdminUserTxServiceImpl implements AdminUserTxService {

    @Resource
    private AdminUserMapper adminUserMapper;

    //支持当前事务，如果当前没有事务，就新建一个事务。这是最常见的选择。 父子是一体的 遇到则合并 必须全部成功才一起提交事务
    @Transactional(propagation = Propagation.REQUIRED)
    public void required(){
        insert("hedy_required",1L);
    }
    //无论如何我独自成一个事务，父事务的成功失败跟我没有关系
    @Transactional(propagation = Propagation.REQUIRES_NEW)
    public void requiresNew(){
        insert("hedy_requires_new",1L);
    }

    //我比较圆滑，遇到事务我就合并一起变成事务，遇到非事务我就非事务
    @Transactional(propagation = Propagation.SUPPORTS)
    public void supports(){
        insert("hedy_supports",0L);
    }
    //我的立场坚定，父事务我不管你，但是我就是不支持事务，始终以非事务状态运行
    @Transactional(propagation = Propagation.NOT_SUPPORTED)
    public void notSupported(){
        insert("hedy_not_supported",0L);
    }

    //只有事务接口才能调用我 否则我抛出异常
    @Transactional(propagation = Propagation.MANDATORY)
    public void mandatory(){
        insert("hedy_mandatory",1L);
    }
    //只有非事务接口才能调用我
    @Transactional(propagation = Propagation.NEVER)
    public void never(){
        insert("hedy_mandatory",1L);
    }

    //嵌套是子事务套在父事务中执行，子事务是父事务的一部分，在进入子事务之前，父事务建立一个回滚点，叫save point，
    // 然后执行子事务，这个子事务的执行也算是父事务的一部分，然后子事务执行结束，父事务继续执行。
    // 子事务失败，重点就在于子事务全部回滚，而父事务回滚到那个save point。如果捕获异常，那么很好，父事务可以继续执行下去，
    //这种方式就是父事务可以兼容子事务的失败，不会影响自己
    //如果没有父事务，那就新起一个事务
    @Override
    public void nested() {

    }

    public void insert(String userName,Long roleId){
        AdminUser adminUser = new AdminUser();
        adminUser.setUserName(userName);
        adminUser.setCreateTime(new Date());
        adminUser.setRoleId(roleId);
        adminUserMapper.insertAdminUser(adminUser);
    }
}
